package com.leantech.android.browser.dialog

import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.leantech.android.browser.databinding.LayoutMenuItemNormalBinding
import com.leantech.android.browser.databinding.LayoutMenuItemToggleBinding
import com.leantech.android.browser.skin.SkinManager
import com.leantech.android.browser.utils.onThrottleClick
import com.qmuiteam.qmui.util.QMUIResHelper
import splitties.resources.txt

class MenuAdapter(
    private val dialog: MenuBottomSheet,
    private val menuItemListener: MenuBottomSheet.MenuItemListener? = null
) :
    ListAdapter<MenuBottomSheet.MenuItem, MenuAdapter.BaseMenuItemViewHolder>(diffCallback) {

    companion object {
        private val diffCallback = object : DiffUtil.ItemCallback<MenuBottomSheet.MenuItem>() {
            override fun areItemsTheSame(
                oldItem: MenuBottomSheet.MenuItem, newItem: MenuBottomSheet.MenuItem
            ): Boolean {
                return oldItem.viewId == newItem.viewId
            }

            override fun areContentsTheSame(
                oldItem: MenuBottomSheet.MenuItem, newItem: MenuBottomSheet.MenuItem
            ): Boolean {
                return oldItem == newItem
            }

            override fun getChangePayload(
                oldItem: MenuBottomSheet.MenuItem,
                newItem: MenuBottomSheet.MenuItem
            ): Any? {
                if (oldItem.enabled != newItem.enabled) {
                    return PayloadEnabled
                } else if (oldItem.selected != newItem.selected) {
                    return PayloadSelected
                }
                return super.getChangePayload(oldItem, newItem)
            }
        }

        private const val ViewTypeNormal = 1
        private const val ViewTypeToggle = 2

        private const val PayloadEnabled = 1
        private const val PayloadSelected = 2


    }

    override fun getItemViewType(position: Int): Int {
        val menuItem = getItem(position)
        return if (menuItem.checkable) ViewTypeToggle else ViewTypeNormal
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseMenuItemViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        return when (viewType) {
            ViewTypeToggle -> {
                val binding = LayoutMenuItemToggleBinding.inflate(layoutInflater, parent, false)
                MenuItemToggleViewHolder(binding)
            }

            else -> {
                val binding = LayoutMenuItemNormalBinding.inflate(layoutInflater, parent, false)
                MenuItemNormalViewHolder(binding)
            }
        }
    }

    override fun onBindViewHolder(holder: BaseMenuItemViewHolder, position: Int) {
        holder.bind(dialog, getItem(position), menuItemListener)
    }

    override fun onBindViewHolder(
        holder: BaseMenuItemViewHolder,
        position: Int,
        payloads: MutableList<Any>
    ) {
        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads)
        } else {
            payloads.forEach { payload ->
                when (payload) {
                    PayloadEnabled -> {
                        holder.onEnabledChanged(getItem(position))
                    }

                    PayloadSelected -> {
                        holder.onSelectedChanged(getItem(position))
                    }

                    else -> {
                        //do nothing
                    }
                }

            }
        }

    }

    abstract class BaseMenuItemViewHolder(view: View) : ViewHolder(view) {
        abstract fun bind(
            dialog: MenuBottomSheet,
            data: MenuBottomSheet.MenuItem,
            menuItemListener: MenuBottomSheet.MenuItemListener? = null
        )

        open fun onEnabledChanged(newData: MenuBottomSheet.MenuItem) {}

        open fun onSelectedChanged(newData: MenuBottomSheet.MenuItem) {}


    }

    class MenuItemNormalViewHolder(private val binding: LayoutMenuItemNormalBinding) :
        BaseMenuItemViewHolder(binding.root) {
        override fun bind(
            dialog: MenuBottomSheet,
            data: MenuBottomSheet.MenuItem,
            menuItemListener: MenuBottomSheet.MenuItemListener?
        ) {
            binding.text.setText(data.text)
            val iconTop = QMUIResHelper.getAttrDrawable(itemView.context, SkinManager.currentTheme(itemView.context), data.icon)
            binding.text.setCompoundDrawablesWithIntrinsicBounds(null, iconTop, null, null)
            binding.text.isSelected = data.selected
            binding.text.isEnabled = data.enabled
            binding.text.onThrottleClick {
                menuItemListener?.onMenuItemClick(dialog, data, bindingAdapterPosition)
            }
        }

        override fun onSelectedChanged(newData: MenuBottomSheet.MenuItem) {
            binding.text.isSelected = newData.selected
        }

        override fun onEnabledChanged(newData: MenuBottomSheet.MenuItem) {
            binding.text.isEnabled = newData.enabled
        }
    }

    class MenuItemToggleViewHolder(private val binding: LayoutMenuItemToggleBinding) :
        BaseMenuItemViewHolder(binding.root) {
        override fun bind(
            dialog: MenuBottomSheet,
            data: MenuBottomSheet.MenuItem,
            menuItemListener: MenuBottomSheet.MenuItemListener?
        ) {
            binding.text.setOnCheckedChangeListener(null)
            binding.text.setTypeface(null,Typeface.NORMAL)
            binding.text.textOff = itemView.context.txt(data.text)
            val iconTop = QMUIResHelper.getAttrDrawable(itemView.context, SkinManager.currentTheme(itemView.context), data.icon)
            binding.text.setCompoundDrawablesWithIntrinsicBounds(null, iconTop, null, null)
            binding.text.textOn = itemView.context.txt(data.textOn)
            binding.text.isChecked = data.checked
            binding.text.isSelected = data.selected
            binding.text.isEnabled = data.enabled

            binding.root.onThrottleClick {
                binding.text.toggle()
            }
            binding.text.setOnCheckedChangeListener { _, isChecked ->
                menuItemListener?.onMenuItemCheckChanged(
                    dialog,
                    data,
                    bindingAdapterPosition,
                    isChecked
                )
            }

        }

        override fun onEnabledChanged(newData: MenuBottomSheet.MenuItem) {
            binding.text.isEnabled = newData.enabled
        }

        override fun onSelectedChanged(newData: MenuBottomSheet.MenuItem) {
            binding.text.isSelected = newData.selected
        }
    }


}